package com.tbit.uqbike.client.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.PatternPool;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.google.auto.service.AutoService;
import com.tbit.uqbike.client.constant.AccountConfigExtConstant;
import com.tbit.uqbike.client.constant.InvoiceRecordConstant;
import com.tbit.uqbike.client.constant.RedisConstant;
import com.tbit.uqbike.client.dao.capital.RefundLogDao;
import com.tbit.uqbike.client.dao.core.AccountConfigExtDao;
import com.tbit.uqbike.client.dao.core.AccountDao;
import com.tbit.uqbike.client.dao.core.BrandRemoteConfigDao;
import com.tbit.uqbike.client.dao.core.InvoiceRecordDao;
import com.tbit.uqbike.client.exception.BaseException;
import com.tbit.uqbike.client.pojo.*;
import com.tbit.uqbike.client.pojo.dto.AddInvoiceRecordDTO;
import com.tbit.uqbike.client.pojo.dto.ReOpenDTO;
import com.tbit.uqbike.client.pojo.dto.ReOpenEditInvoiceRecordDTO;
import com.tbit.uqbike.client.pojo.dto.ReOpenInvoiceRecordDTO;
import com.tbit.uqbike.client.pojo.newEntity.AccountConfigExt;
import com.tbit.uqbike.client.pojo.vo.InvoiceCardLogVO;
import com.tbit.uqbike.client.pojo.vo.InvoiceRideLogVO;
import com.tbit.uqbike.client.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.util.ByteArrayDataSource;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 发票
 *
 * @Author:BUGTian
 * @DATE: 2023/8/29
 */
@Service
@Slf4j
public class InvoiceRecordServiceImpl implements InvoiceRecordService {

    @Autowired
    private TokenService tokenService;

    @Autowired
    private InvoiceRecordDao invoiceRecordDao;

    @Resource
    private JavaMailSender mailSender;
    @Resource
    private AccountDao accountDao;
    @Value("${spring.mail.username:}")
    private String mailUserName;
    @Autowired
    private RefundLogDao refundLogDao;
    @Autowired
    private RedisService redisService;
    @Resource
    private AccountConfigExtDao accountConfigExtDao;
    @Resource
    private AutoInvoiceService autoInvoiceService;
    @Resource
    private BrandRemoteConfigDao brandRemoteConfigDao;

    @Override
    public Result<List<InvoiceRideLogVO>> queryInvoiceRideLog(String token, Date startTime, Date endTime, Long minMoney, Long maxMoney) {
        Integer userId = getUser(token).getUserId();
        List<InvoiceRideLogVO> invoiceRideLogVOList = getInvoiceRideLogVOList(userId, startTime, endTime, minMoney, maxMoney, null, null);
        return Result.success(invoiceRideLogVOList);
    }

    public List<InvoiceRideLogVO> getInvoiceRideLogVOList(Integer userId, Date startTime, Date endTime, Long minMoney, Long maxMoney, List<String> orderList, Integer invoiceId) {
        List<InvoiceRideLogVO> newInvoiceRideLogVOList = new ArrayList<>();
        List<InvoiceRideLogVO> invoiceRideLogVOList = invoiceRecordDao.queryInvoiceRideLog(userId, startTime, endTime, minMoney, maxMoney, orderList, invoiceId);
        Map<String, Map<String, Object>> map = refundLogDao.selectRefundRideOrder(userId);
        for (InvoiceRideLogVO invoiceRideLogVO : invoiceRideLogVOList) {
            Map<String, Object> refundMsgMap = map.get(invoiceRideLogVO.getOrderNO());
            Integer refundMoney = 0;
            if (refundMsgMap != null) {
                refundMoney = Integer.valueOf(refundMsgMap.get("refundMoney").toString());
            }
            invoiceRideLogVO.setMoney(invoiceRideLogVO.getMoney() - refundMoney);
            if (invoiceRideLogVO.getMoney() > 0) {
                newInvoiceRideLogVOList.add(invoiceRideLogVO);
            }
        }
        return newInvoiceRideLogVOList;
    }

    @Override
    public Result<List<InvoiceCardLogVO>> queryInvoiceCardLog(String token, Date startTime, Date endTime, Long minMoney, Long maxMoney, Integer rechargeType) {
        Integer userId = getUser(token).getUserId();
        List<InvoiceCardLogVO> invoiceCardLogVOList = getInvoiceCardLogVOList(userId, startTime, endTime, minMoney, maxMoney, rechargeType, null, null);
        return Result.success(invoiceCardLogVOList);
    }

    public List<InvoiceCardLogVO> getInvoiceCardLogVOList(Integer userId, Date startTime, Date endTime, Long minMoney, Long maxMoney, Integer rechargeType, List<String> orderList, Integer invoiceId) {
        List<InvoiceCardLogVO> newInvoiceCardLogVOList = new ArrayList<>();
        List<InvoiceCardLogVO> invoiceCardLogVOList = invoiceRecordDao.queryInvoiceCardLog(userId, startTime, endTime, minMoney, maxMoney, rechargeType, orderList, invoiceId);
        Map<String, Map<String, Object>> map = refundLogDao.selectRefundCardOrder(userId);
        for (InvoiceCardLogVO invoiceCardLogVO : invoiceCardLogVOList) {
            Map<String, Object> refundMsgMap = map.get(invoiceCardLogVO.getOrderNO());
            Integer refundMoney = 0;
            if (refundMsgMap != null) {
                refundMoney = Integer.valueOf(refundMsgMap.get("refundMoney").toString());
            }
            invoiceCardLogVO.setMoney(invoiceCardLogVO.getMoney() - refundMoney);
            if (invoiceCardLogVO.getMoney() > 0) {
                newInvoiceCardLogVOList.add(invoiceCardLogVO);
            }
        }
        return newInvoiceCardLogVOList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result addInvoiceRecord(String token, AddInvoiceRecordDTO addInvoiceRecordDTO) {
        User user = getUser(token);
        if (!StringUtils.hasText(addInvoiceRecordDTO.getCompanyTitle()) || addInvoiceRecordDTO.getTitleType() == null) {
            return Result.error("抬头不能为空");
        }
        if (!StringUtils.hasText(addInvoiceRecordDTO.getEmail())) {
            return Result.error("邮箱不能为空");
        }
        if (!PatternPool.EMAIL.matcher(addInvoiceRecordDTO.getEmail()).matches()) {
            return Result.error("邮箱地址不正确");
        }
        List<String> orderList = addInvoiceRecordDTO.getOrderList();
        Integer orderType = addInvoiceRecordDTO.getOrderType();
        if (CollectionUtil.isEmpty(orderList) || orderType == null) {
            return Result.error("订单信息不能为空");
        }
        InvoiceMoney invoiceMoney = checkAndGetMoney(user.getUserId(), orderList, orderType, null);
        Double money = invoiceMoney.getMoney();
        addInvoiceRecordDTO.addInit(user, money);
        InvoiceRecord invoiceRecord = new InvoiceRecord();
        BeanUtils.copyProperties(addInvoiceRecordDTO, invoiceRecord);
        //添加开票信息和绑定记录
        invoiceRecord.initFlowId(InvoiceRecordConstant.NOT_IS_REOPEN);
        //判断是否自动开票
        invoiceRecord.setInvoiceOpenType(this.getInvoiceOpenType(addInvoiceRecordDTO.getBrandId()));
        invoiceRecordDao.insertInvoiceRecord(invoiceRecord);
        invoiceRecordDao.insertInvoiceRecordBound(invoiceRecord.getId(), invoiceMoney.getList(), InvoiceRecordConstant.STATUS_APPLY);
        //如果是自动开票则调用开票接口
        if (Objects.equals(invoiceRecord.getInvoiceOpenType(),InvoiceRecordConstant.INVOICE_OPEN_TYPE_AUTO_INVOICE)){
            try {
                autoInvoiceService.autoInvoicing(invoiceRecord);
            }catch (Exception e){
                log.info("自动开票失败,invoiceRecord:{}，e",JSON.toJSONString(invoiceRecord),e);
            }
        }
        return Result.success();
    }

    @Override
    public Result<List<InvoiceRecord>> queryInvoiceRecord(String token) {
        User user = tokenService.getUser(token);
        return Result.success(invoiceRecordDao.queryInvoiceRecord(user.getUserId()));
    }

    @Override
    public Result<List<InvoiceRideLogVO>> getRideLogById(String token, Integer id) {
        return Result.success(getInvoiceRideLogVOList(getUser(token).getUserId(), null, null, null, null, null, id));
    }

    @Override
    public Result<List<InvoiceCardLogVO>> getCardLogById(String token, Integer id) {
        return Result.success(getInvoiceCardLogVOList(getUser(token).getUserId(), null, null, null, null, null, null, id));
    }

    @Override
    public Result<Object> canReopenInvoiceRecord(String token, Integer id, Integer orderType, Date startTime, Date endTime, Long minMoney, Long maxMoney, Integer rechargeType) {
        if (id == null || orderType == null) {
            return Result.error("参数有误");
        }
        Integer userId = getUser(token).getUserId();
        switch (orderType) {
            case InvoiceRecordConstant.ORDER_TYPE_RIDE:
                List<InvoiceRideLogVO> invoiceRideLogVOList = getInvoiceRideLogVOList(userId, startTime, endTime, minMoney, maxMoney, null, null)
                        .stream()
                        .filter(i -> InvoiceRecordConstant.STATUS_NOT.equals(i.getStatus()) || id.equals(i.getInvoiceId()))
                        .collect(Collectors.toList());
                return Result.success(invoiceRideLogVOList);
            case InvoiceRecordConstant.ORDER_TYPE_CARD:
                List<InvoiceCardLogVO> invoiceCardLogVOList = getInvoiceCardLogVOList(getUser(token).getUserId(), startTime, endTime, minMoney, maxMoney, rechargeType, null, null)
                        .stream()
                        .filter(i -> InvoiceRecordConstant.STATUS_NOT.equals(i.getStatus()) || id.equals(i.getInvoiceId()))
                        .collect(Collectors.toList());
                return Result.success(invoiceCardLogVOList);
            default:
                return Result.error("订单类型有误");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result reOpenInvoiceRecord(String token, ReOpenInvoiceRecordDTO reOpenInvoiceRecordDTO) {
        User user = getUser(token);
        Integer id = reOpenInvoiceRecordDTO.getId();
        Integer orderType = reOpenInvoiceRecordDTO.getOrderType();
        List<String> orderList = reOpenInvoiceRecordDTO.getOrderList();
        if (id == null || orderType == null || CollectionUtil.isEmpty(orderList)) {
            return Result.error("缺少必要参数");
        }
        InvoiceRecord invoiceRecord = invoiceRecordDao.queryInvoiceRecordById(id);
        if (invoiceRecord == null) {
            return Result.error("发票信息不存在");
        }
        InvoiceMoney invoiceMoney = checkAndGetMoney(user.getUserId(), orderList, orderType, id);
        Double money = invoiceMoney.getMoney();
        invoiceRecordDao.updateInvoiceRecordBound(id, InvoiceRecordConstant.STATUS_REOPEN);
        Date applyTime = new Date();
        invoiceRecordDao.updateInvoiceRecord(id, InvoiceRecordConstant.STATUS_REOPEN, applyTime,null);
        //添加新的开票信息和绑定记录
        invoiceRecord
                .setInvoiceAmount(money)
                .setId(null)
                .setStatus(InvoiceRecordConstant.STATUS_REOPEN_NEW)
                .setApplyTime(applyTime);
        invoiceRecord.initFlowId(InvoiceRecordConstant.IS_REOPEN);
        invoiceRecordDao.insertInvoiceRecord(invoiceRecord);
        invoiceRecordDao.insertInvoiceRecordBound(invoiceRecord.getId(), invoiceMoney.getList(), InvoiceRecordConstant.STATUS_REOPEN_NEW);
        invoiceRecordDao.updateNewId(id, invoiceRecord.getId());
        return Result.success();
    }

    @Override
    public Result reOpenEditInvoiceRecord(String token, ReOpenEditInvoiceRecordDTO reOpenEditInvoiceRecordDTO) {
        if (!PatternPool.EMAIL.matcher(reOpenEditInvoiceRecordDTO.getEmail()).matches()) {
            return Result.error("邮箱地址不正确");
        }
        Integer id = reOpenEditInvoiceRecordDTO.getId();
        InvoiceRecord invoiceRecord = invoiceRecordDao.queryInvoiceRecordById(id);
        if (invoiceRecord == null) {
            return Result.error("发票信息不存在");
        }
        if (InvoiceRecordConstant.STATUS_REOPEN.equals(invoiceRecord.getStatus())) {
            return Result.error("请勿重复重开");
        }
        Date applyTime = new Date();
        reOpenEditInvoiceRecordDTO.setTime(applyTime);
        invoiceRecordDao.updateInvoiceRecordBound(id, InvoiceRecordConstant.STATUS_REOPEN);
        invoiceRecordDao.updateInvoiceRecord(id, InvoiceRecordConstant.STATUS_REOPEN, applyTime,null);
        invoiceRecord
                .setTitleType(reOpenEditInvoiceRecordDTO.getTitleType())
                .setCompanyTitle(reOpenEditInvoiceRecordDTO.getCompanyTitle())
                .setCompanyTaxNumber(reOpenEditInvoiceRecordDTO.getCompanyTaxNumber())
                .setCompanyAddress(reOpenEditInvoiceRecordDTO.getCompanyAddress())
                .setCompanyPhone(reOpenEditInvoiceRecordDTO.getCompanyPhone())
                .setBank(reOpenEditInvoiceRecordDTO.getBank())
                .setAccount(reOpenEditInvoiceRecordDTO.getAccount())
                .setStatus(InvoiceRecordConstant.STATUS_REOPEN_NEW)
                .setApplyTime(applyTime)
                .setEmail(reOpenEditInvoiceRecordDTO.getEmail());
        invoiceRecord.initFlowId(InvoiceRecordConstant.IS_REOPEN);
        invoiceRecordDao.insertInvoiceRecord(invoiceRecord);
        invoiceRecordDao.insertInvoiceRecordBound(invoiceRecord.getId(), invoiceRecordDao.selectBandOrder(id), InvoiceRecordConstant.STATUS_REOPEN_NEW);
        invoiceRecordDao.updateNewId(id, invoiceRecord.getId());
        return Result.success();
    }

    @Override
    public Result reSend(String token, String email, Integer id) {
        if (!PatternPool.EMAIL.matcher(email).matches()) {
            return Result.error("邮箱地址不正确");
        }
        User user = getUser(token);
        if (redisService.get(RedisConstant.INVOICE_RECORD_RETRY + user.getUserId() + id) != null) {
            return Result.error("操作频繁,请稍后再试");
        }
        InvoiceRecord invoiceRecord = invoiceRecordDao.queryInvoiceRecordById(id);
        if (invoiceRecord == null) {
            return Result.error("发票历史不存在");
        }
        String brandName = Optional.ofNullable(accountDao.getByAccountId(user.getUserId()))
                .map(Account::getName)
                .orElse("");
        String title = String.format("%s电子发票", brandName);
        try {
            //手动开票
            if (Objects.equals(invoiceRecord.getInvoiceOpenType(),InvoiceRecordConstant.INVOICE_OPEN_TYPE_HAND_INVOICE)){
                this.handSendInvoice(invoiceRecord,email,title);
            }else {//自动开票
                autoInvoiceService.reSendInvoiceEmail(invoiceRecord,email);
            }
        } catch (Exception e) {
            log.error("电子发票邮件发送失败", e);
            throw new BaseException("电子发票邮件发送失败");
        }
        redisService.add(RedisConstant.INVOICE_RECORD_RETRY + user.getUserId() + id, email, 180);
        return Result.success();
    }

    @Override
    public Result editEmail(String token, String email, Integer id) {
        if (!PatternPool.EMAIL.matcher(email).matches()) {
            return Result.error("邮箱地址不正确");
        }
        User user = getUser(token);
        InvoiceRecord invoiceRecord = invoiceRecordDao.queryInvoiceRecordById(id);
        if (invoiceRecord == null) {
            return Result.error("发票历史不存在");
        }
        if (!invoiceRecord.getUserId().equals(user.getUserId())) {
            return Result.error("无权操作");
        }
        invoiceRecordDao.updateEmail(id, email);
        return Result.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result reOpenInvoiceRecordNew(String token, ReOpenDTO reOpenDTO) {
        log.info("reOpenInvoiceRecordNew----->token:{},reOpenDTO:{}",token, JSON.toJSONString(reOpenDTO));
        User user = getUser(token);
        ReOpenEditInvoiceRecordDTO reOpenEditMsg = reOpenDTO.getReOpenEditMsg();
        ReOpenInvoiceRecordDTO reOpenOrder = reOpenDTO.getReOpenOrder();
        if (!PatternPool.EMAIL.matcher(reOpenEditMsg.getEmail()).matches()) {
            return Result.error("邮箱地址不正确");
        }
        Integer id = reOpenEditMsg.getId();
        InvoiceRecord invoiceRecord = invoiceRecordDao.queryInvoiceRecordById(id);
        if (invoiceRecord == null) {
            return Result.error("发票信息不存在");
        }
        if (InvoiceRecordConstant.STATUS_REOPEN.equals(invoiceRecord.getStatus())) {
            return Result.error("请勿重复重开");
        }
        Integer orderType = reOpenOrder.getOrderType();
        List<String> orderList = reOpenOrder.getOrderList();
        if (id == null || orderType == null || CollectionUtil.isEmpty(orderList)) {
            return Result.error("缺少必要参数");
        }
        //是否自动开票
        boolean autoInvoice = Objects.equals(invoiceRecord.getInvoiceOpenType(), InvoiceRecordConstant.INVOICE_OPEN_TYPE_AUTO_INVOICE);
        String invoiceNumber = invoiceRecord.getInvoiceNumber();
        Integer status = invoiceRecord.getStatus();
        Date applyTime = new Date();
        InvoiceMoney invoiceMoney = checkAndGetMoney(user.getUserId(), orderList, orderType, id);
        Double money = invoiceMoney.getMoney();
        invoiceRecordDao.updateInvoiceRecordBound(id, autoInvoice ? InvoiceRecordConstant.STATUS_abandon : InvoiceRecordConstant.STATUS_REOPEN);
        invoiceRecordDao.updateInvoiceRecord(id, autoInvoice ? InvoiceRecordConstant.STATUS_abandon : InvoiceRecordConstant.STATUS_REOPEN, applyTime,applyTime);
        invoiceRecord
                .setInvoiceAmount(money)
                .setTitleType(reOpenEditMsg.getTitleType())
                .setCompanyTitle(reOpenEditMsg.getCompanyTitle())
                .setCompanyTaxNumber(reOpenEditMsg.getCompanyTaxNumber())
                .setCompanyAddress(reOpenEditMsg.getCompanyAddress())
                .setCompanyPhone(reOpenEditMsg.getCompanyPhone())
                .setBank(reOpenEditMsg.getBank())
                .setAccount(reOpenEditMsg.getAccount())
                .setStatus(autoInvoice ? InvoiceRecordConstant.STATUS_APPLY : InvoiceRecordConstant.STATUS_REOPEN_NEW)
                .setApplyTime(applyTime)
                .setEmail(reOpenEditMsg.getEmail())
                .setInvoiceNumber(autoInvoice ? null : invoiceRecord.getInvoiceNumber());
        invoiceRecord.initFlowId(InvoiceRecordConstant.IS_REOPEN);
        invoiceRecordDao.insertInvoiceRecord(invoiceRecord);
        invoiceRecordDao.insertInvoiceRecordBound(invoiceRecord.getId(), invoiceMoney.getList(), autoInvoice ?  InvoiceRecordConstant.STATUS_APPLY : InvoiceRecordConstant.STATUS_REOPEN_NEW);
        invoiceRecordDao.updateNewId(id, invoiceRecord.getId());
        //如果是自动开票,并且已经开票则调用申请红冲接口
        if (autoInvoice){
            if (org.apache.commons.lang3.StringUtils.isBlank(invoiceNumber)
                    && Objects.equals(status,InvoiceRecordConstant.STATUS_APPLY)){//如果是自动开票，并且没有
                throw new BaseException("正在自动开票，暂时无法重新开票，请10分钟后再试！");
            }
            autoInvoiceService.dealRedChong(id, InvoiceRecordConstant.RED_CHONG_CONFIRM);
        }
        return Result.success();
    }

    /**
     * 校验参数合法性并返回金额
     *
     * @param userId    用户id
     * @param orderList 订单编号列表
     * @param orderType 订单类型
     * @param invoiceId 发票历史id
     * @return
     */
    private InvoiceMoney checkAndGetMoney(Integer userId, List<String> orderList, Integer orderType, Integer invoiceId) {
        InvoiceMoney invoiceMoney = new InvoiceMoney();
        List<InvoiceOrderBandMoney> list = new ArrayList<>();
        //根据不同的订单类型进行校验
        Integer money = 0;
        switch (orderType) {
            case InvoiceRecordConstant.ORDER_TYPE_RIDE:
                List<InvoiceRideLogVO> invoiceRideLogVOList = getInvoiceRideLogVOList(userId, null, null, null, null, orderList, null);
                if (invoiceRideLogVOList.size() != orderList.size()) {
                    throw new BaseException("订单不存在");
                }
                //已开票的骑行订单
                List<String> collectRide = invoiceRideLogVOList.stream().filter(i -> invoiceId == null ? !InvoiceRecordConstant.STATUS_NOT.equals(i.getStatus()) : (!InvoiceRecordConstant.STATUS_NOT.equals(i.getStatus()) && !Objects.equals(invoiceId, i.getInvoiceId()))).map(InvoiceRideLogVO::getOrderNO).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(collectRide)) {
                    throw new BaseException(String.format("骑行订单%s已开票,请重新选择", collectRide.toString()));
                }
                for (InvoiceRideLogVO invoiceRideLogVO : invoiceRideLogVOList) {
                    money += invoiceRideLogVO.getMoney();
                    list.add(new InvoiceOrderBandMoney(invoiceRideLogVO.getOrderNO(), NumberUtil.div(invoiceRideLogVO.getMoney().intValue(), 100)));
                }
                invoiceMoney.setMoney(NumberUtil.div(money.intValue(), 100));
                break;
            case InvoiceRecordConstant.ORDER_TYPE_CARD:
                List<InvoiceCardLogVO> invoiceCardLogVOList = getInvoiceCardLogVOList(userId, null, null, null, null, null, orderList, null);
                if (invoiceCardLogVOList.size() != orderList.size()) {
                    throw new BaseException("订单不存在");
                }
                //查询已开票的套餐订单
                List<String> collectCard = invoiceCardLogVOList.stream().filter(i -> invoiceId == null ? !InvoiceRecordConstant.STATUS_NOT.equals(i.getStatus()) : (!InvoiceRecordConstant.STATUS_NOT.equals(i.getStatus()) && !Objects.equals(invoiceId, i.getInvoiceId()))).map(InvoiceCardLogVO::getOrderNO).collect(Collectors.toList());
                if (CollectionUtil.isNotEmpty(collectCard)) {
                    throw new BaseException(String.format("套餐订单%s已开票,请重新选择", collectCard.toString()));
                }
                for (InvoiceCardLogVO invoiceCardLogVO : invoiceCardLogVOList) {
                    money += invoiceCardLogVO.getMoney();
                    list.add(new InvoiceOrderBandMoney(invoiceCardLogVO.getOrderNO(), NumberUtil.div(invoiceCardLogVO.getMoney().intValue(), 100)));
                }
                invoiceMoney.setMoney(NumberUtil.div(money.intValue(), 100));
                break;
            default:
                throw new BaseException("订单类型有误");
        }
        invoiceMoney.setList(list);
        return invoiceMoney;
    }


    private User getUser(String token) {
        User user = tokenService.getUser(token);
        if (user == null) {
            throw new BaseException("-20005", "用户不存在");
        }
        return user;
    }

    /**
     * @description: 获取品牌的开票方式
     * @author: mo.shanyong
     * @date: 2025/4/2 14:18
     * @param: brandId 品牌id
     * @return: java.lang.Integer
     */
    private Integer getInvoiceOpenType(Integer brandId){
        BrandRemoteConfig brandRemoteConfig = new BrandRemoteConfig();
        brandRemoteConfig.setConfigType(InvoiceRecordConstant.AUTO_INVOICE_SWITCH);
        brandRemoteConfig.setAccountId(brandId);
        BrandRemoteConfig remoteConfig = brandRemoteConfigDao.getByAccountIdAndType(brandRemoteConfig);
        if (Objects.isNull(remoteConfig) || org.apache.commons.lang3.StringUtils.isBlank(remoteConfig.getParamKV())){
            return InvoiceRecordConstant.INVOICE_OPEN_TYPE_HAND_INVOICE;
        }
        String[] split = remoteConfig.getParamKV().split("=");
        if (Objects.equals(split[1],AccountConfigExtConstant.EXT_CONFIG_OPEN)){
            return InvoiceRecordConstant.INVOICE_OPEN_TYPE_AUTO_INVOICE;
        }
        return InvoiceRecordConstant.INVOICE_OPEN_TYPE_HAND_INVOICE;
    }

    /**
     * @description: 手动发送发票到邮箱
     * @author: mo.shanyong
     * @date: 2025/4/7 20:16
     * @param: invoiceRecord
     * @param: email
     * @param: title 邮件主题
     */
    private void handSendInvoice(InvoiceRecord invoiceRecord,String email,String title) throws Exception {
        InputStream inputStream = HttpUtil.createGet(invoiceRecord.getUrl()).execute().bodyStream();
        if (inputStream == null) {
            log.info("获取发票文件失败");
            throw new BaseException("发票获取失败");
        }
        MimeMessageHelper messageHelper = new MimeMessageHelper(mailSender.createMimeMessage(), true);
        messageHelper.setFrom(mailUserName);
        messageHelper.setTo(email);
        messageHelper.setSubject(title);
        messageHelper.setText("");
        messageHelper.addAttachment(title + ".pdf", new ByteArrayDataSource(inputStream, "application/pdf"));
        messageHelper.setSentDate(new Date());
        mailSender.send(messageHelper.getMimeMessage());
    }
}
